package com.gurumades.jsonform.client;


import java.util.HashMap;
import java.util.Vector;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.gurumades.jsonform.client.constants.AppMessages;
import com.gurumades.jsonform.client.forms.FieldsetWidget;
import com.gurumades.jsonform.client.forms.FormItemViewIF;
import com.gurumades.jsonform.client.forms.FormWidgetFactory;
import com.gurumades.jsonform.client.presenter.*;

public class JsonFormView extends Composite implements JsonFormPresenter.Display {
	private JSONObject displayObject;
	private HashMap<String, JSONObject> displayObects = new HashMap<String,JSONObject>(); 
	private HashMap<String, FormItemViewIF> formItems = new HashMap<String,FormItemViewIF>(); 
	private FlowPanel flexTable;
	

	public JsonFormView() {
		
		VerticalPanel verticalPanel = new VerticalPanel();
		initWidget(verticalPanel);
		
		flexTable = new FlowPanel();
		verticalPanel.add(flexTable);
		flexTable.setWidth("100%");	
	}

	/**
	 * Default method to build a screen
	 * @param displayFields
	 * @param flexTable
	 */
	public void setData(JSONValue displayFieldsArray, JSONObject displayObject, String userRole){
		this.displayObject = displayObject;	

		displayObects.clear();
		formItems.clear();
		
		if (displayFieldsArray.isArray() == null) return;
		
		flexTable.clear();
		JSONArray array = (JSONArray)displayFieldsArray;
		for (int row = 0; row<array.size(); row++){
			JSONObject jsonRow = (JSONObject) array.get(row);
			FieldsetWidget fieldset = new FieldsetWidget();
			fieldset.setTitle(getString("label", jsonRow), getString("iconURL", jsonRow));
			
			if (jsonRow.containsKey("items")) {
				JSONObject items = jsonRow.get("items").isObject();
				if (items != null && items.containsKey("item")) {
					if (items.get("item").isArray() != null) {
						JSONArray line = items.get("item").isArray();
						for (int i = 0; i < line.size(); i++) {
							JSONObject formItem = line.get(i).isObject();
							
							String rowID = getString("id",formItem);
							this.displayObects.put(rowID, formItem);
							
							addRow(rowID,formItem, displayObject, fieldset);
						}
					}
				}
			}
			
			fieldset.getPanel().setOpen(!getBoolean("collapsed", jsonRow));
			
			final DisclosurePanel panel = fieldset.getPanel();
			if (!getBoolean("collapsible", jsonRow)) {
				fieldset.getPanel().setAnimationEnabled(false);
				fieldset.getPanel().addCloseHandler(new CloseHandler<DisclosurePanel>() {
					
					@Override
					public void onClose(CloseEvent<DisclosurePanel> event) {
						panel.setOpen(true);
					}
				});
			}
			
			fieldset.setDescription(getString("description", jsonRow));
			//fieldset.setTitle(getString("label", jsonRow));
			
			flexTable.add(fieldset);
		}		
	}
	

	private void addRow(String rowID, JSONObject jsonRow, JSONObject displayObject, FieldsetWidget flexTable){
		try{
			
			if (getBoolean("visible", jsonRow)) {
				FormItemViewIF row = FormWidgetFactory.createWidget(getString("type", jsonRow));
				row.initFormItem(displayObject.get(rowID), jsonRow);
				flexTable.addFormItem(row.asWidget());
				
				formItems.put(rowID, row);
			}
			
		} catch (Exception ex){
		}
	}
	
	@Override
	public HashMap<String, FormItemViewIF> getFormItems() {
		return formItems;
	}
	
	private String getString(String key, JSONObject o) {
		return JSONUtils.getString(key, o);
	}
	
	private boolean getBoolean(String key, JSONObject o) {
		return JSONUtils.getBoolean(key, o);
	}
	
	public JSONObject getDisplayObject() {
		return displayObject;
	}

	public HashMap<String, JSONObject> getDisplayFields() {
		return displayObects;
	}
}